import { UploadFileInfo } from "naive-ui";
import { usePlayListStore } from '../store/index'
import { nanoid } from 'nanoid'
import { Howl } from 'howler';
import { checkUserIp, checkUserAddress } from '../ajax/api'
import { updateUserClientInfo, updateUserIpInfo } from '../ajax'

/**
 * 随机返回一个naive-ui的type
 * @returns 
 */

interface NaiveType {
    type: 'default' | 'primary' | 'success' | 'info' | 'warning' | 'error'
}
export function randomNaiveType(): NaiveType['type'] {
    const colorArray: NaiveType['type'][] = ['default', 'primary', 'success', 'info', 'warning', 'error']
    return colorArray[Math.round(Math.random() * 5)]
}

/**
 * 文件大小格式化
 * @param bytes 
 * @returns 
 */
export function bytesToSize(bytes: number): string {
    if (bytes === 0) return '0 B';
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    // Math.log() 返回数字的自然对数 log(b)/log(a)=loga(b)) 换底公式 log以a为底b的对数
    // Math.floor(x) -- 向下取整，返回小于或等于x的值
    // Math.pow(x,y) -- 返回以x的y次幂，等同于x^y的数值表达式
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return (bytes / Math.pow(k, i)).toFixed(1) + ' ' + sizes[i];
}


/**
 * 文件时长格式化
 * @param secs 
 * @returns 
 */
export function formatTimeToMinSec(secs: number) {
    const minutes = Math.floor(secs / 60) || 0;
    const seconds = (secs - minutes * 60) || 0;

    return minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
}


/**
 * 等级可视化
 * @param level 
 */
export function formatLevel(level: number) {

    let i = 0
    const levelArray = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
    /* 
        等级1：1天，等级2：5天，等级3：15天，等级4：90天，等级5：365天，等级6：730天，
        等级7：1095天，等级8：1460天，等级9：1825天，等级10：2190天，等级11：2555天，等级12：2920天
    */
    const matchArray = [
        86400, 432000, 1296000, 7776000,
        31536000, 63072000, 94608000, 126144000,
        157680000, 189216000, 220752000, 252288000
    ]

    for (let index = 0; index < matchArray.length; index++) {
        const element = matchArray[index];

        if (level >= 252288000) {
            i = 11
            break;
        }

        if (level <= 86400) {
            i = 0
            break;
        }

        if (level <= element) {
            i = Number((index - 1).toFixed(0))
            break;
        }
    }

    return levelArray[i]
}


/**
 * 计算下一等级的时长
 * @param level string
 * @returns day和nextLevlInfo
 */
export function calNextLevel(level: number) {

    // 当前累计播放时长
    const day = (level / 3600 / 24).toFixed(2)
    let nextLevlInfo = ''

    /* 
        等级1：1天，等级2：5天，等级3：15天，等级4：90天，等级5：365天，等级6：730天，
        等级7：1095天，等级8：1460天，等级9：1825天，等级10：2190天，等级11：2555天，等级12：2920天
    */
    const matchArray = [
        86400, 432000, 1296000, 7776000,
        31536000, 63072000, 94608000, 126144000,
        157680000, 189216000, 220752000, 252288000
    ]

    for (let index = 0; index < matchArray.length; index++) {
        const element = matchArray[index];

        if (level >= 252288000) {
            nextLevlInfo = '当前等级已为最高等级'
            break;
        }

        if (level <= 86400) {
            nextLevlInfo = `距离下一等级还需要累计听歌：${((86400 - level) / 24 / 3600).toFixed(2)}天`
            break;
        }

        if (level <= element) {
            nextLevlInfo = `距离下一等级还需要累计听歌：${((element - level) / 24 / 3600).toFixed(2)}天`
            break;
        }
    }

    return { day, nextLevlInfo }
}


/**
 * 上传音乐时格式限制
 * @param file 
 * @returns 
 */
export function matchMusicExt(file: UploadFileInfo) {

    let auth = false

    // 允许的文件格式
    const allExt = ['opus', 'flac', 'webm', 'weba', 'wav', 'ogg', 'm4a', 'mp3', 'oga', 'mid', 'amr', 'aiff', 'wma', 'au', 'aac']

    for (let index = 0; index < allExt.length; index++) {
        const element = allExt[index];
        const reg = new RegExp(element, 'ig')
        if (reg.test(file.name.split('.')[`${file.name.split('.').length - 1}`])) {
            auth = true
            break;
        }
    }

    return auth

}

/**
 * 上传音乐封面时格式限制
 * @param file 
 * @returns 
 */
export function matchMusicCoverExt(file: UploadFileInfo) {

    let auth = false

    // 允许的文件格式
    const allExt = ['xbm', 'tif', 'jfif', 'ico', 'tiff', 'gif', 'svg', 'jpeg', 'svgz', 'jpg', 'webp', 'png', 'bmp', 'pjp', 'apng', 'pjpeg', 'avif']

    for (let index = 0; index < allExt.length; index++) {
        const element = allExt[index];
        const reg = new RegExp(element, 'ig')
        if (reg.test(file.name.split('.')[`${file.name.split('.').length - 1}`])) {
            auth = true
            break;
        }
    }

    return auth
}

/**
 * 上传音乐歌词时格式限制
 * @param file 
 * @returns 
 */
export function matchMusicLyricExt(file: UploadFileInfo) {

    let auth = false

    // 允许的文件格式
    const allExt = ['lrc']

    for (let index = 0; index < allExt.length; index++) {
        const element = allExt[index];
        const reg = new RegExp(element, 'ig')
        if (reg.test(file.name.split('.')[`${file.name.split('.').length - 1}`])) {
            auth = true
            break;
        }
    }

    return auth
}


/**
 * 获取音乐的时长
 * @param file 
 * @returns Promise<string>
 */
export async function getMusicDuration(file: UploadFileInfo): Promise<string> {

    return new Promise((resolve, _) => {
        const audio = document.createElement('audio')
        audio.src = 'file:///' + file.file?.path
        audio.style.display = "none"
        audio.preload = "auto"

        audio.addEventListener("canplay", () => {
            let duration = formatTimeToMinSec(Math.round(audio.duration))
            audio.remove()
            resolve(duration)
        });

    })

}


/**
 * 导入音频到对应的播放列表里
 * @param playListMode 
 * @param files 
 */
export async function importPlayListMode(playListMode: PlayConfigState['playListMode'], array: SearchAudioData[]) {

    const usePlayList = usePlayListStore()

    // 导入前先清空
    usePlayList[`${playListMode}`].length = 0

    // 导入对应播放库
    array.map((item) => {
        (usePlayList[`${playListMode}`] as PlayListState[]).push({
            audioId: item.audioId, _id: item._id, audioName: item.singer + ' - ' + item.audioName,
            audioCover: item.audioCover, audioVersion: item.audioVersion, audioSrc: item.audioSrc,
            size: item.size, duration: item.duration, lyric: item.lyric, play: false,
            singer: item.singer, singerId: item.singerId, write: item.write, writeId: item.writeId,
            audioMv: item.audioMv, uploader: item.uploader, like: playListMode == 'likePlayList' ? true : false,
        })
    })

}

/**
 * 对传入的播放列表进行我的喜欢匹配
 * @param array 
 */
export async function matchMyLike(playListMode: PlayConfigState['playListMode']) {

    const usePlayList = usePlayListStore()

    if (playListMode == 'audioLibrary') {

        (usePlayList[`${playListMode}`] as PlayListState[]).map((e) => {

            let auth = false

            for (let index = 0; index < usePlayList.likePlayList.length; index++) {
                const i = usePlayList.likePlayList[index];
                if (i.audioId == e._id) {
                    auth = true
                }
            }

            auth ? e.like = true : e.like = false

        })

    }

}


/**
 * 导入本地音乐时时限制文件格式
 * @param options 
 * @returns 
 */
export function matchLocalMusicExt(options: { file: UploadFileInfo, fileList: Array<UploadFileInfo>, event?: Event }): boolean {

    const usePlayList = usePlayListStore()

    // 允许的文件格式
    const allExt = ['opus', 'flac', 'webm', 'weba', 'wav', 'ogg', 'm4a', 'mp3', 'oga', 'mid', 'amr', 'aiff', 'wma', 'au', 'aac']
    // 因为是动态的update，每次只需要读取最后一个文件即可
    const file = options.fileList[`${options.fileList.length - 1}`]

    let auth = false

    for (let index = 0; index < allExt.length; index++) {
        const element = allExt[index];
        const reg = new RegExp(element, 'ig')
        if (reg.test(file.name.split('.')[`${file.name.split('.').length - 1}`])) {
            auth = true
            break;
        }
    }

    if (auth) {
        const howl = new Howl({
            src: ['file:///' + file.file?.path],
            onload: function () {
                usePlayList.importLocalPlayList({
                    audioId: nanoid(),
                    audioName: file.name,
                    audioSrc: 'file:///' + file.file?.path,
                    audioCover: '',
                    size: file.file!.size,
                    duration: formatTimeToMinSec(Math.round(howl.duration())),
                    play: false,
                    write: '',
                    writeId: '',
                    lyric: '',
                    singer: '',
                    singerId: ''
                })
                howl.unload()
            }
        })

    }

    return auth

}


/**
 * 获取设备系统类型
 * @returns {string} 返回的系统名称
 */
export function getOSname(): string {
    let e = "Unknown";
    if (window.navigator.userAgent.indexOf("Windows NT 10.0") != -1)
        e = "Windows 10/11";
    if (window.navigator.userAgent.indexOf("Windows NT 6.2") != -1)
        e = "Windows 8";
    if (window.navigator.userAgent.indexOf("Windows NT 6.1") != -1)
        e = "Windows 7";
    if (window.navigator.userAgent.indexOf("Windows NT 6.0") != -1)
        e = "Windows Vista";
    if (window.navigator.userAgent.indexOf("Windows NT 5.1") != -1)
        e = "Windows XP";
    if (window.navigator.userAgent.indexOf("Windows NT 5.0") != -1)
        e = "Windows 2000";
    if (window.navigator.userAgent.indexOf("Mac") != -1)
        e = "Mac/iOS";
    if (window.navigator.userAgent.indexOf("X11") != -1)
        e = "UNIX";
    if (window.navigator.userAgent.indexOf("Linux") != -1)
        e = "Linux";
    return e
}


/**
 * 更新用户客户端IP信息
 * @returns Promise<{ _ip: string, loginDate: number, status:boolean }>
 */
export async function refreshUserIpInfo(): Promise<{ _ip: string, loginDate: number, status: boolean }> {

    return new Promise(async (resolve, reject) => {

        let _ip = ''

        // 获取ip
        const IP = await checkUserIp()

        if (IP.data.ip) { // 成功获取ip

            _ip = IP.data.ip
            const { data } = await updateUserIpInfo(_ip)
            if (data.code == 0) {
                resolve({ _ip, loginDate: data.data.loginDate, status: true })
            } else {
                reject({ _ip, loginDate: 0, status: false })
            }

        } else { // 获取ip失败
            reject({ _ip, loginDate: 0, status: false })
        }

    })


}


/**
 * 更新用户客户端设备信息
 * @returns Promise<{ _client: string, status: boolean }>
 */
export async function refreshUserClientInfo(_ip: string): Promise<{ _client: string, status: boolean }> {

    return new Promise(async (resolve, reject) => {

        let _address = ''
        let _client = ''

        // 获取设备信息
        let _os = getOSname()

        // 获取地址
        const ADDRESS = await checkUserAddress(_ip)
        if (ADDRESS.data.status == '0') { // 获取地址成功
            // 拼接client地址
            _address = ADDRESS.data.data[0].location
            _client = _address + ' -- ' + _os

            // 同步服务器数据
            const { data } = await updateUserClientInfo(_client)
            if (data.code == 0) {
                resolve({ _client, status: true })
            } else {
                reject({ _client, status: false })
            }
        } else {  // 获取地址失败
            reject({ _client, status: false })
        }

    })

}
